//Copyright 2010 Balazs Keri, Imre Keri
//
//This file is part of FireworksCreator.
//
//FireworksCreator is free software: you can redistribute it and/or modify
//it under the terms of the GNU General Public License as published by
//the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.
//
//FireworksCreator is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with FireworksCreator.  If not, see <http://www.gnu.org/licenses/>.
//
#ifndef _MODEL_PARTICLETEMPLATE_H
#define _MODEL_PARTICLETEMPLATE_H
//
#include <global.h>
#include <QVector>
#include <QStringList>
#include <common/identified.h>
#include <common/range.h>
#include "randomdouble.h"
#include "randomcolor.h"
#include "emittertemplate_fwd.h"
//
namespace model
{
class ParticleTemplate:public Identified
{
   Q_OBJECT
   Q_DISABLE_COPY(ParticleTemplate)
//structures
public:
   struct TimeMark
   {
      enum Mode
      {
         from_start,
         from_end,
         from_other
      };
      Mode mode;
      RandomDouble time;
      QString other;
   //functions
      TimeMark();
      TimeMark(const TimeMark &p_other);
      TimeMark &operator=(const TimeMark &p_other);
   };
   struct EmitterBlock
   {
      QString name;
      double interval_min;
      double interval_max;
      QString time1;
      QString time2;
      EmitterTemplate *emitter;
   //functions
      EmitterBlock();
      EmitterBlock(const EmitterBlock &p_other);
      EmitterBlock &operator=(const EmitterBlock &p_other);
   };
   struct ColorControlPoint
   {
      RandomColor color;
      QString time;
   //functions
      ColorControlPoint();
      ColorControlPoint(const ColorControlPoint &p_other);
      ColorControlPoint(const QString &p_time, const RandomColor &p_color) : color(p_color), time(p_time) {}
      ColorControlPoint &operator=(const ColorControlPoint &p_other);
   };
   struct FloatControlPoint
   {
      RandomDouble value;
      QString time;
   //functions
      FloatControlPoint();
      FloatControlPoint(const FloatControlPoint &p_other);
      FloatControlPoint(const QString &p_time, const RandomDouble &p_value) : value(p_value), time(p_time) {}
      FloatControlPoint &operator=(const FloatControlPoint &p_other);
   };
   enum Shape
   {
      shape_point,
      shape_quad,
      shape_quad_trianglestrip,
      shape_hexagon
   };
   enum TileSpeedMode
   {
      tile_speed_relative,
      tile_speed_absolute
   };
//construction
public:
   ParticleTemplate(QObject *p_parent=0);
   ~ParticleTemplate();
//data access
public:
   QString get_name()const;
   void set_name(QString p_name);
   bool get_visible()const;
   void set_visible(bool p_visible);
   RandomDouble get_life_time()const;
   void set_life_time(const RandomDouble &p_life_time);
   float get_density()const;
   void set_density(float p_density);
   bool get_gravitation_enabled()const;
   void set_gravitation_enabled(bool p_gravitation_enabled);
   bool get_friction_enabled()const;
   void set_friction_enabled(bool p_friction_enabled);
   Shape get_shape()const;
   void set_shape(Shape p_shape);
   QString get_texture_file()const;
   void set_texture_file(QString p_texture_file);
   unsigned int get_tile_s()const;
   unsigned int get_tile_t()const;
   void set_tile_s(unsigned int s);
   void set_tile_t(unsigned int t);
   void set_tile(unsigned int p_tile_s,unsigned int p_tile_t);
   float get_num_tiles()const;
   void set_num_tiles(float p_num_tiles);
   TileSpeedMode get_tile_speed_mode()const;
   void set_tile_speed_mode(TileSpeedMode p_tile_speed);
   QString compute_time_mark_ancestor(const QString &p_time_mark_name)const;
   QStringList compute_time_mark_time_sort(QString &p_error,QStringList &p_bad_tm)const;
   void store_data(QDataStream &p_stream)const;
   void restore_data(RestoreStream &p_stream);
//data
public:
   QHash<QString,TimeMark> time_marks;
   QList<EmitterBlock> emitters;
   QList<ColorControlPoint> color_control_points;
   QList<FloatControlPoint> alpha_control_points;
   QList<FloatControlPoint> size_control_points;
   QList<FloatControlPoint> radius_control_points;
private:
   QString name;
   bool visible;
   RandomDouble life_time;
   float density;
   bool gravitation_enabled;
   bool friction_enabled;
   Shape shape;
   QString texture_file;
   int tile_s;
   int tile_t;
   float num_tiles;
   TileSpeedMode tile_speed_mode;
   bool compute_rel_range(QVector<QVector<Range> > &p_rel_ranges,QVector<QVector<char> > &p_rel_state,const QStringList &p_tm,unsigned int p_from,unsigned int p_to)const;
   void compute_rel_state(const QVector<QVector<Range> > &p_rel_ranges,QVector<QVector<char> > &p_rel_state,unsigned int p_i,unsigned int p_j)const;
};
}
//
QDataStream &operator<<(QDataStream &p_stream,const model::ParticleTemplate::TimeMark &p_tm);
RestoreStream &operator>>(RestoreStream &p_stream,model::ParticleTemplate::TimeMark &p_tm);
QDataStream &operator<<(QDataStream &p_stream,const model::ParticleTemplate::EmitterBlock &p_eb);
RestoreStream &operator>>(RestoreStream &p_stream,model::ParticleTemplate::EmitterBlock &p_eb);
QDataStream &operator<<(QDataStream &p_stream,const model::ParticleTemplate::FloatControlPoint &p_fcp);
RestoreStream &operator>>(RestoreStream &p_stream,model::ParticleTemplate::FloatControlPoint &p_fcp);
QDataStream &operator<<(QDataStream &p_stream,const model::ParticleTemplate::ColorControlPoint &p_ccp);
RestoreStream &operator>>(RestoreStream &p_stream,model::ParticleTemplate::ColorControlPoint &p_ccp);
RestoreStream &operator>>(RestoreStream &p_stream,model::ParticleTemplate *&p_pt);
//
#endif
